﻿#include "..\..\include\Server\CAsyncServer.h"

CAsyncServer::CAsyncServer()
{
	this->m_sckListen = INVALID_SOCKET;
	m_ClientList.clear();
	m_uId = 0;
}

CAsyncServer::~CAsyncServer()
{
	
}

//开启服务
BOOL CAsyncServer::Start(ULONG ulServer, UINT uPort, HWND hWnd)
{
	if (this->InitWinsock() == FALSE)
	{
		return FALSE;
	}

	//创建用于监听的套接字
	m_sckListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(m_sckListen == INVALID_SOCKET)
	{
		debug.Trace("创建套接字失败，错误：%d\n", ::WSAGetLastError());
		return FALSE;
	}

	//绑定到地址族
	sockaddr_in addr;
	addr.sin_addr.S_un.S_addr = ulServer;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(uPort);

	int nBind = ::bind(this->m_sckListen, (const sockaddr*)&addr, sizeof(addr));
	if (nBind == SOCKET_ERROR)
	{
		debug.Trace("绑定到地址族失败！错误：%d\n", ::WSAGetLastError());
		return FALSE;
	}

	//将套接字设置为消息模式
	int nSelect = ::WSAAsyncSelect(this->m_sckListen, hWnd, WM_SOCKET, FD_ACCEPT | FD_CONNECT | FD_CLOSE);
	if (nSelect != 0)
	{
		debug.Trace("设置套接字模式失败！错误：%d\n", ::WSAGetLastError());
		return FALSE;
	}

	//开始监听客户端
	int nListen = ::listen(this->m_sckListen, 5);
	if(nListen == SOCKET_ERROR)
	{
		debug.Trace("监听客户端失败！错误：%d", ::WSAGetLastError());
		return FALSE;
	}

	return TRUE;
}

void CAsyncServer::Stop()
{
	//关闭所有客户端套接字
	for (list<CLIENT_INFO>::iterator iter = m_ClientList.begin();
		iter != m_ClientList.end(); iter++)
	{
		::closesocket(iter->s);
	}

	//清空客户端列表
	this->m_ClientList.clear();

	//关闭监听套接字
	::closesocket(this->m_sckListen);
	::WSACleanup();
}

//初始化Winsock库
BOOL CAsyncServer::InitWinsock()
{
	//构造一个WSADATA结构的指针
	WSADATA wsaData;

	//调用WSAStartup()初始化Winsock库，这里我们统一使用Winsock2的子版本，2.2版。用MAKEWORD宏来构造版本号。
	int nResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (nResult != 0)
	{
		//调用错误的情况
		::OutputDebugStringA("初始化Winsock库失败！\n");
		WSACleanup();
		return FALSE;
	}

	//判断加载的版本号是否正常
	if (HIBYTE(wsaData.wVersion) != 2 || LOBYTE(wsaData.wVersion) != 2)
	{
		::OutputDebugStringA("初始化Winsock库失败，版本号异常！\n");
		WSACleanup();
		return FALSE;
	}

	return TRUE;
}

//添加Client
void CAsyncServer::AddClient(CLIENT_INFO client)
{
	this->m_ClientList.push_back(client);
}

//删除Client
void CAsyncServer::DelClient(SOCKET &s)
{
	if (m_ClientList.empty())
		return;

	for (list<CLIENT_INFO>::iterator iter = m_ClientList.begin(); 
		iter != m_ClientList.end(); iter++)
	{
		if (iter->s == s)
		{
			m_ClientList.erase(iter);
			return;
		}
	}
}

//查询Client信息
void CAsyncServer::QueryClient(const SOCKET &s, CLIENT_INFO *client)
{
	if (m_ClientList.empty())
		return;

	for (list<CLIENT_INFO>::iterator iter = m_ClientList.begin(); 
		iter != m_ClientList.end(); iter++)
	{
		if (iter->s == s)
		{
			//返回结构指针
			//*client = iter;
			memcpy(client, (void*)&iter, sizeof(iter));
			return;
		}
	}
}
